<?php
/**
 * 订单控制器
 * Created by PhpStorm.
 * User: lz
 * Date: 2015/6/30
 * Time: 11:45
 */
class OrderApp extends MallbaseApp {

    /**
     * 生成订单
     * @author lz
     * @date 2015/07/09
     */
    public function add() {
        /* 提交方法 */
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
        if ($method != 'POST') {
            $this->ajax_return(FLAG_ERROR, '非法的请求！');
        }
        $user_id = $this->checkLogin();
        if (!$user_id) {
            $this->ajax_return(FLAG_ERROR, '请您进行登陆！');
        }
        $bases_info = $this->add_order($user_id);
//        $bases_info[0]['order_amount'] = 0.01;
        $this->ajax_return(FLAG_OK, '操作成功！', $bases_info);
    }


    /**
     * 微信生成订单
     * @author jiayanxiu
     * @date 2015/05/13
     */
    public function wxadd() {
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/WxPay.pub.config.php");
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/WxPayPubHelper.php");
        /* 提交方法 */
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
        if ($method != 'POST') {
            $this->ajax_return(FLAG_ERROR, '非法的请求！');
        }
        $user_id = $this->checkLogin();
        if (!$user_id) {
            $this->ajax_return(FLAG_ERROR, '请您进行登陆！');
        }

        //插入订单信息
        $bases_info = $this->add_order($user_id);
        $info = $bases_info[0];
        //微信统一下单
        $input = new UnifiedOrder_pub();
        $input->setParameter('body', $info['body']);
        $input->setParameter('out_trade_no', $info["order_sn"]);
        $input->setParameter('total_fee', floatval($info["order_amount"] * 100));
//        $input->setParameter('total_fee', 1);
        $input->setParameter('time_start', date("YmdHis"));
        $input->setParameter('time_expire', date("YmdHis", time() + 600));
        $input->setParameter('notify_url', 'http://www.heshetrends.com/api/notify/wxappnotify');
        $input->setParameter('trade_type', 'APP');
        $row = $input->getPrepayId();
        if ($row['return_code'] != 'SUCCESS' && $row['result_code'] != 'SUCCESS') {
            $this->ajax_return(FLAG_ERROR, '微信支付失败！');
        }

        $timestamp = time();
        $res['timestamp']    = $timestamp;
        $res['appid']        = $row['appid'];
        $res['partnerid']    = $row['mch_id'];
        $res['noncestr']     = $row['nonce_str'];
        $res['prepayid']     = $row['prepay_id'];
        $res['package']      = 'Sign=WXPay';
        $res['sign'] = $input->getSign($res);
        $this->ajax_return(FLAG_OK, '操作成功！', $res);
    }



    /**
     * 生成订单
     * @param $user_id
     * @return array
     * @author jyx
     * @date 2015/07/31
     */
    private function add_order($user_id) {
        $wish_id = $this->get_gp('wish_id', 'P');//心愿单Id
        $spec_id = $this->get_gp('spec_id', 'P');
        $spec_id = $spec_id ? intval($spec_id) : 0;
        $wish_id = $wish_id ? intval($wish_id) : 0;
        if (!$spec_id) {
            $this->ajax_return(FLAG_ERROR, '不存在的商品属性id！');
        }
        /* 获取收货人地址信息 */
        $consignee = $this->checkConsigneeInfo();

        /* 获取商品信息 */
        $goods_info = $this->getGoodsInfo();

        $order_model = m('order');
        $order_goods_model = m('ordergoods');
        $order_model->begin();//开启事物

        /* 根据提供的商品信息生成订单 */
        foreach ($goods_info['items'] as $key=>$val) {
            /* 处理订单基本信息 */
            $base_info = $this->handleOrderInfo($val, $user_id);

            /* 处理订单收货人信息 */
            $consignee_info = $this->handleConsigneeInfo($consignee);

            //检测商品库存量
            $bool = $this->checkStock($spec_id);
            if ($bool === false) {
                $this->ajax_return(FLAG_ERROR, '商品库存不足！');
            }

            //如果存在心愿单，并且心愿单已经完成，则此订单已经付款
            $tmps = array();
            if ($wish_id) {
                $tmps = $this->wish($wish_id, $user_id);
                if ($tmps['flag']) {
                    $base_info['status'] = ORDER_ACCEPTED;
                }
            }
            /* 插入订单信息 */
            $order_id    = $order_model->add($base_info);
            if (!$order_id) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入订单信息失败！');
            }
            //减少商品的库存,增加销量
            if ($wish_id) {
                //不需要付款
                if ($tmps['flag'] === true) {
                    $this->updateStock($wish_id,$tmps['goods_id'], $tmps['spec_id'],$base_info['order_sn']);
                }
                //需要支付余额
                if ($tmps['flag'] === false) {
                    $base_info['order_amount'] = $tmps['price'];
                }
            }
            //更新心愿单信息的订单信息
            if ($wish_id && $order_id) {
                $sql = "UPDATE ".DB_PREFIX."wish SET order_sn='{$base_info['order_sn']}' WHERE wish_id={$wish_id}";
                $res = $order_model->query($sql);
                if ($res === false) {
                    $order_model->rollback();
                    $this->ajax_return(FLAG_ERROR, '更新心愿单信息失败！');
                }

            }

            /* 插入收货人信息 */
            $consignee_info['order_id'] = $order_id;
            $order_extm_model = m('orderextm');
            $flag = $order_extm_model->add($consignee_info);
            if ($flag === false) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入收货人信息失败！');
            }
            /* 插入商品信息 */
            $goods_items = array();
            foreach ($goods_info['items'] as $value)
            {
                $goods_items[] = array(
                    'order_id'      =>  $order_id,
                    'goods_id'      =>  $value['goods_id'],
                    'goods_name'    =>  $value['goods_name'],
                    'spec_id'       =>  $value['spec_id'],
                    'specification' =>  $value['specification'],
                    'price'         =>  $value['price'],
                    'supply_price'  =>  $value['supply_price'],
                    'quantity'      =>  $value['quantity'],
                    'goods_image'   =>  $value['goods_image'],
                );
                $body = $value['goods_name'];//商品名称
            }
            $rs = $order_goods_model->add(addslashes_deep($goods_items)); //防止二次注入
            if ($rs === false) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入商品信息失败！');
            }
            $base_info['body'] = $body;
            $bases_info[] = $base_info;
        }
        $order_model->commit();
        return $bases_info;
    }


    /**
     * 计算出是否要支付金额
     * @param $wish_id
     * @param $user_id
     * @return bool
     * @author jyx
     * @date 2015/07/30
     */
    private function wish($wish_id, $user_id) {
        $model = m('wish');
        //查询出商品的总金额
        $sql = "SELECT w.wish_id,w.goods_id,w.spec_id,gs.price FROM ".DB_PREFIX."wish w LEFT JOIN ".DB_PREFIX."goods_spec gs
				ON w.spec_id=gs.spec_id WHERE w.wish_id={$wish_id} AND user_id={$user_id}";
        $tmp = $model->getRow($sql);
        //查询出捐赠的总金额
        $sql = "SELECT SUM(donate_price) AS total_price FROM ".DB_PREFIX."wish_log WHERE wish_id={$wish_id} AND `status`=1";
        $temp = $model->getRow($sql);
        $price = floatval($tmp['price'] - $temp['total_price']);
        if ($price < 0 ) {
            $price = 0;
        }
        //如果金额相等，则去生成一条订单，入库,不需要支付！
        if ($temp['total_price'] == $tmp['price'] || $price == 0) {
            $tmp['flag'] = true;
        } else {
            $tmp['flag'] = false;
            $tmp['price'] = $price;
        }
        return $tmp;
    }


    /**
     * 更新销量和库存量
     * @param $wish_id
     * @param $goods_id
     * @param $spec_id
     * @param $order_sn
     * @return bool
     * @quthor jyx
     * @date 2015/07/31
     */
    private function updateStock($wish_id,$goods_id, $spec_id, $order_sn) {
        $model = m('wish');
        //更新心愿单信息
        $sql = "UPDATE ".DB_PREFIX."wish SET flag=1,order_sn='{$order_sn}' WHERE wish_id={$wish_id}";
        $flag = $model->query($sql);
        if ($flag === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新心愿单信息失败！');
        }
        //更新销量
        $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_statistics WHERE goods_id={$goods_id}";
        if ($model->getRow($sql)) {
            $sql = "UPDATE ".DB_PREFIX."goods_statistics SET sales=sales+1 WHERE goods_id={$goods_id}";
            $rs = $model->query($sql);
        } else {
            $sql = "INSERT INTO ".DB_PREFIX."goods_statistics (goods_id,sales) VALUES ({$goods_id}, 1)";
            $rs = $model->query($sql);
        }
        //更新销量信息
        if ($rs === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新销量信息失败！');
        }
        //更新库存信息
        $sql = "UPDATE ".DB_PREFIX."goods_spec SET stock = stock-1 WHERE spec_id = {$spec_id}";
        $update = $model->query($sql);
        if ($update === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新库存信息失败！');
        }
        return true;
    }

    /**
     * 检测商品库存量
     * @param $spec_id
     * @return bool
     * @author jyx
     * @date 2015/08/03
     */
    private function checkStock($spec_id) {
        $model = m('goods');
        $sql = "SELECT stock FROM ".DB_PREFIX."goods_spec WHERE spec_id={$spec_id}";
        $tmp = $model->getRow($sql);
        if ($tmp['stock'] > 0) {
            return true;
        }
        return false;

    }



    /**
     * 获取外部传递过来的商品信息
     * @return array
     */
    private function getGoodsInfo() {
        $data = array(
            'type'          => 'material',  //商品类型
            'otype'         => 'normal',    //订单类型
            'allow_coupon'  => true,        //是否允许使用优惠券
        );
        //获取传递过来的商品扩展信息的spec_id
        $spec_id = $this->get_gp('spec_id', 'P');
        $quantity = $this->get_gp('quantity', 'P');
        $type = $this->get_gp('type', 'P');
        $type = $type ? 'cart' : '';
        if (!$spec_id) {
            $this->ajax_return(FLAG_ERROR, '不存在的spec_id！');
        }
        $quantity = $quantity ? intval($quantity) : 1;
        if ($type == 'cart') {
            $sql = "SELECT c.*,s.store_name,s.owner_name FROM ".DB_PREFIX."cart c LEFT JOIN ".DB_PREFIX."store s ON c.store_id=s.store_id WHERE c.spec_id IN ({$spec_id})";
        } else {
            $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_spec WHERE spec_id IN ({$spec_id}) GROUP BY goods_id";//查询出商品的goods_id
            $sql = "SELECT goods_id,goods_name,store_id,default_image,supply_price,is_act,discount_price,spec_qty FROM ".DB_PREFIX."goods WHERE goods_id IN ({$sql}) GROUP BY store_id";//查询出商铺的id
            $sql = "SELECT gs.*,g.store_id,g.goods_name,g.default_image,g.supply_price,g.is_act,g.discount_price,g.spec_qty FROM ".DB_PREFIX."goods_spec gs LEFT JOIN ($sql) AS g ON gs.goods_id=g.goods_id WHERE gs.spec_id IN ({$spec_id})";//关连商铺id和商品扩展信息
            $sql = "SELECT gs.*,s.store_name,s.owner_name FROM ({$sql}) gs LEFT JOIN ".DB_PREFIX."store s ON gs.store_id=s.store_id";//查询出商品和商铺的信息
        }
        $model = m('cart');
        $goods = $model->getAll($sql);

        if (!$goods) {
            $this->ajax_return(FLAG_ERROR, '您购买的商品信息不存在！');
        }
        //查询活动商品信息
        $sql = "SELECT start_time,end_time,quantity FROM
                    ".DB_PREFIX."active a
                RIGHT JOIN ".DB_PREFIX."active_goods b ON a.id = b.active_id
                WHERE b.goods_id = ".$goods['0']['goods_id'];
        $active = $model->getRow($sql);
        $now = time();

        //判断用户是否购买过特价商品
        $isBuy = $this->is_buy($goods['0']['goods_id']);

        if(!$isBuy && $active && $active['start_time']<$now && $now<$active['end_time'] && $active['quantity']) {
            //是活动;  //限购
            if($quantity > 1) {
                $this->ajax_return(FLAG_ERROR, '活动商品只限购一件！');
            }
            $start = $active['start_time'];
            $end = $active['end_time'];
            $now = time();
            if($now < $start) {
                $this->ajax_return(FLAG_ERROR ,'抢购活动还未开始！');
            }
            if($now > $end) {
                $this->ajax_return(FLAG_ERROR ,'抱歉，抢购已经结束！');
            }
            foreach ($goods as $key=>$val) {
                $val['quantity']  = 1;                                      //商品的总数量
                $val['subtotal']  = $val['discount_price'];                 //当前商品小计总价
                $val['discount']  = $val['price']-$val['discount_price'];   //当前商品优惠了多少钱
                $data['quantity'] = 1;                                      //商品的总数量
                $data['amount']   = $val['discount_price'];                 //商品总价

                $val['supply_price'] = ($val['spec_supply_price'] > 0) ? floatval($val['spec_supply_price']) : floatval($val['supply_price']);
                $val['goods_image'] = $val['default_image'] ? $val['default_image'] : Conf::get('default_goods_image');
                $val['type'] = 'material';
                $val['otype'] = 'normal';
                $data['items'][] = $val;
            }
            return $data;
        } else {
            //不是活动
            $row = explode(',', $quantity);
            foreach ($goods as $key=>$val) {
                if ($type == 'cart') {
                    //如果是从购物车中买商品是可以查询出商品数量的
                    $val['subtotal'] = $val['quantity'] * $val['price'];         //当前商品小计总价
                    $data['quantity'] += $val['quantity'];                       //商品总数量
                    $data['amount'] += $val['subtotal'];                         //商品总价
                } else {
                    $val['quantity'] = $row[$key];                              //商品的总数量
                    $val['subtotal'] = $val['quantity'] * $val['price'];        //当前商品小计总价
                    $data['quantity'] += $val['quantity'];                      //商品的总数量
                    $data['amount'] += $val['subtotal'];                        //商品总价
                }
                $val['supply_price'] = ($val['spec_supply_price'] > 0) ? floatval($val['spec_supply_price']) : floatval($val['supply_price']);
                if ($type == 'cart') {
                    $val['goods_image'] = $val['goods_image'] ? $val['goods_image'] : Conf::get('default_goods_image');
                } else {
                    $val['goods_image'] = $val['default_image'] ? $val['default_image'] : Conf::get('default_goods_image');
                }
                $val['type'] = 'material';
                $val['otype'] = 'normal';
                $data['items'][] = $val;

            }
            return $data;
        }

    }

    /**
     * 处理订单信息
     * @param $goods_info
     * @param $user_id
     * @return array
     * @author jiayanxiu
     * @date 2015/02/07
     */
    private function handleOrderInfo($goods_info, $user_id) {
        /* 默认都是待付款 */
        $order_status = ORDER_PENDING;

        /* 买家信息 */
        $sql = "SELECT user_name,email FROM ".DB_PREFIX."member WHERE user_id={$user_id}";
        $model = m('member');
        $user_info = $model->getRow($sql);
        //获取店铺邮费
        $sql = "SELECT first_price FROM ".DB_PREFIX."shipping WHERE store_id={$goods_info['store_id']}";
        $model_ship = m('order');
        $shipping_fee = $model_ship->getOne($sql);
        /* 返回基本信息 @todo */
        $return = array(
            'order_sn'      =>  $this->genOrderSn(),
            'type'          =>  $goods_info['type'],
            'extension'     =>  'normal',
            'seller_id'     =>  $goods_info['store_id'],
            'seller_name'   =>  addslashes($goods_info['store_name']),
            'buyer_id'      =>  $user_id,
            'buyer_name'    =>  addslashes($user_info["user_name"]),
            'buyer_email'   =>  $user_info["email"],
            'status'        =>  $order_status,
            'add_time'      =>  gmtime(),
            'goods_amount'  =>  $goods_info['subtotal'],
//            'order_amount'  =>  $goods_info['subtotal'] + $shipping_fee - $goods_info['discount'],
//            'order_amount'  =>  $goods_info['subtotal'] - $goods_info['discount'],//暂时都变成包邮了
            'order_amount'  =>  $goods_info['subtotal'],
            'supply_amount' =>  $goods_info['supply_price'],
            'discount'      =>  isset($goods_info['discount']) ? $goods_info['discount'] : 0,
            'postscript'    =>  $this->get_gp('postscript', 'P'),
        );
        return $return;
    }

    /**
     * 检测收货地址
     * @return mixed
     * @author jiayanxiu
     * @date 2015/02/06
     */
    private function checkConsigneeInfo() {
        $consignee['consignee'] = $this->get_gp('consignee', 'P');
        $consignee['region_name'] = $this->get_gp('region_name', 'P');
        $consignee['address'] = $this->get_gp('address', 'P');
        $consignee['phone_tel'] = $this->get_gp('phone_tel', 'P');
        $consignee['phone_mob'] = $this->get_gp('phone_mob', 'P');
        /* 验证收货人信息填写是否完整 */
        if (!$consignee['consignee']){
            $this->ajax_return(FLAG_ERROR, '收货人姓名不能为空！');
        }
        if (!$consignee['region_name']) {
            $this->ajax_return(FLAG_ERROR, '省级市地址不能为空！');
        }
        if (!$consignee['address']){
            $this->ajax_return(FLAG_ERROR, '详细收货地址不能为空！');
        }
        if (!$consignee['phone_tel'] && !$consignee['phone_mob']){
            $this->ajax_return(FLAG_ERROR, '请您至少填写一个联系方式！');
        }
        if ($consignee['phone_mob']) {
            if (strlen($consignee['phone_mob']) != 11) {
                $this->ajax_return(FLAG_ERROR, '手机号码长度为11位数字，请您重新填写！');
            }
            if (!$this->is_phone($consignee['phone_mob'])) {
                $this->ajax_return(FLAG_ERROR, '手机号码格式不正确，请您重新填写！');
            }
        }
        if ($consignee['phone_tel']) {
            if (!$this->is_mobile($consignee['phone_mob'])) {
                $this->ajax_return(FLAG_ERROR, '电话号码格式不正确，请您重新填写！');
            }
        }
        return $consignee;
    }

    /**
     * 处理收货人信息
     * @param $consignee
     * @return array|bool
     */
    private function handleConsigneeInfo($consignee) {
        //@todo 计算配送费用
        return array(
            'consignee'     =>  $consignee['consignee'],
//            'region_id'     =>  $consignee['region_id'],
            'region_name'   =>  $consignee['region_name'],
            'address'       =>  $consignee['address'],
            'zipcode'       =>  $consignee['zipcode'],
            'phone_tel'     =>  $consignee['phone_tel'],
            'phone_mob'     =>  $consignee['phone_mob'],
//            'shipping_id'   =>  $consignee_info['shipping_id'],
//            'shipping_name' =>  addslashes($shipping_info['shipping_name']),
//            'shipping_fee'  =>  $shipping_fee,
        );
    }

    /**
     * 生成订单号
     * @return string
     * @author jiayanxiu
     * @date 2015/02/02
     */
    private function genOrderSn() {
        /* 选择一个随机的方案 */
        mt_srand((double) microtime() * 1000000);
        $timestamp = gmtime();
        $y = date('y', $timestamp);
        $z = date('z', $timestamp);
        $order_sn = $y . str_pad($z, 3, '0', STR_PAD_LEFT) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);

        $model_order = m('order');
        $orders = $model_order->find('order_sn=' . $order_sn);
        if (empty($orders)) {
            /* 否则就使用这个订单号 */
            return $order_sn;
        }

        /* 如果有重复的，则重新生成 */
        return $this->genOrderSn();
    }

    /**
     * 商品抢购
     */
    public function snapping() {
        $config = require ROOT_PATH.'/data/config.qiniu.php';

        //抢购商品！
        $model = m('recommend');
        $sql = "SELECT
                    active_id,title,goods_id,start_time,end_time,quantity
                FROM
                    ".DB_PREFIX."active_goods a
                LEFT JOIN ".DB_PREFIX."active b ON a.active_id = b.id
                ORDER BY sort_order DESC LIMIT 0,1";
        $active = $model->getRow($sql);

        //查询活动封面图片
        $sql = "SELECT file_path FROM ".DB_PREFIX."active_file WHERE item_id=".$active['active_id']." AND is_act=1";
        $images = $model->getAll($sql);
        foreach($images as $key =>$val) {
            $val = $config['qiniu_url'].$val['file_path'];
            $images[$key] = $val;
        }

        $active['image'] = $images['0'];
        $this->ajax_return(FLAG_OK,'',$active);
    }

    /**
     * 判断用户是否购买过特价商品
     * @param $goods_id
     * @return bool
     */
    public function is_buy($goods_id) {
        $user_id = $this->checkLogin();
        //获取商品优惠价
        $sql = "SELECT discount_price FROM ".DB_PREFIX."goods WHERE goods_id = ".$goods_id;
        $model = m('goods');
        $discount = $model->getRow($sql);
        $discount = $discount['discount_price'];
        $sql = "SELECT
                    rec_id
                FROM
                    ".DB_PREFIX."order_goods a
                LEFT JOIN ".DB_PREFIX."order b ON a.order_id = b.order_id
                WHERE
                    buyer_id = ".$user_id."
                AND goods_id = ".$goods_id." AND order_amount = ".$discount;
        $isBuy = $model->getRow($sql);
        if($isBuy) {
            return true;    //用户已经购买了该优惠商品
        } else {
            return false;   //用户没有买过该优惠商品
        }
    }

}